package com.tianci.appstore.ui.detail.dialog;

import android.app.Dialog;
import android.content.Context;
import android.graphics.Bitmap;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.view.Gravity;
import android.view.KeyEvent;
import android.view.View;
import android.view.animation.Animation;
import android.view.animation.Animation.AnimationListener;
import android.view.animation.AnimationUtils;
import android.widget.FrameLayout;
import android.widget.FrameLayout.LayoutParams;
import android.widget.ImageView;
import android.widget.ImageView.ScaleType;
import android.widget.LinearLayout;
import android.widget.TextView;

import com.coocaa.x.framework.utils.LogUtils;
import com.tianci.appstore.R;
import com.tianci.appstore.ui.SkinManager;
import com.tianci.appstore.ui.util.UICommon;
import com.tianci.appstore.utils.SkyConstants;
import com.tianci.appstore.utils.SkyNetImageCache;
import com.tianci.appstore.utils.SkyNetImageCache.ImageLoadListener;

import java.util.List;

public class ShotDialog extends Dialog implements ImageLoadListener {
    private Context mContext;
    private ImageView image1, image2;
    private LinearLayout indicator;
    private ImageView leftArrow, rightArrow;
    private TextView indicatorText;
    private int showDuration = 3000;
    private int animDuration = 280;
    private boolean indicatorShown = false;
    private Animation animShow, animHide;

    private boolean circulate = true;

    private int crtImageIndex = 0;
    private int crtBitmapIndex = 0;
    private List<String> urlList;
    private boolean[] isLoaded;
    private Bitmap loadedBitmap;
    private PreviewListener listener;

    private Animation inLeftRight;
    private Animation outLeftRight;
    private Animation inRightLeft;
    private Animation outRightLeft;

    private static final int REFRESH_IMAGE = 1;
    private static final int HIDE_INDICATOR = 2;
    private static final int LOAD_BIG_BITMAP = 3;
    private int delayDuration = 300;

    public ShotDialog(Context context) {
        super(context, R.style.full_screen_dlg);
        this.mContext = context;
        getWindow().setLayout(SkyConstants.Div(1920), SkyConstants.Div(1080));
        // TODO Auto-generated constructor stub
        createView();
        initAnimation();
    }

    private void initAnimation() {
        inLeftRight = AnimationUtils.loadAnimation(mContext, R.anim.in_leftright);
        outLeftRight = AnimationUtils.loadAnimation(mContext, R.anim.out_leftright);
        inRightLeft = AnimationUtils.loadAnimation(mContext, R.anim.in_rightleft);
        outRightLeft = AnimationUtils.loadAnimation(mContext, R.anim.out_rightleft);
        inLeftRight.setDuration(200);
        outLeftRight.setDuration(200);
        inRightLeft.setDuration(200);
        outRightLeft.setDuration(200);
        inLeftRight.setFillAfter(true);
        outLeftRight.setFillAfter(true);
        inRightLeft.setFillAfter(true);
        outRightLeft.setFillAfter(true);
        inLeftRight.setAnimationListener(animListener);
        inRightLeft.setAnimationListener(animListener);

        animShow = AnimationUtils.loadAnimation(mContext, R.anim.in_downup);
        animShow.setDuration(animDuration);
        animShow.setFillBefore(true);
        animShow.setFillAfter(true);
        animHide = AnimationUtils.loadAnimation(mContext, R.anim.out_updown);
        animHide.setDuration(animDuration);
        animHide.setFillBefore(true);
        animHide.setFillAfter(true);
    }

    private boolean isRunningAnim = false;
    private AnimationListener animListener = new AnimationListener() {
        @Override
        public void onAnimationStart(Animation animation) {
            // TODO Auto-generated method stub
            isRunningAnim = true;
        }

        @Override
        public void onAnimationRepeat(Animation animation) {
            // TODO Auto-generated method stub

        }

        @Override
        public void onAnimationEnd(Animation animation) {
            // TODO Auto-generated method stub
            isRunningAnim = false;
            drawBitmap();
        }
    };

    private void createView() {
        FrameLayout contentView = new FrameLayout(mContext);
        SkinManager.setBackground(contentView, R.drawable.ui_sdk_app_bg);
        this.setContentView(contentView, new LayoutParams(
                SkyConstants.Div(1920), SkyConstants.Div(1080)));

        image1 = new ImageView(mContext);
        image1.setTag(-1);
        image1.setImageDrawable(SkinManager.getResDrawable(R.drawable.pic_nopic));
        image1.setScaleType(ScaleType.CENTER_INSIDE);
        image2 = new ImageView(mContext);
        image2.setTag(-2);
        image2.setImageDrawable(SkinManager.getResDrawable(R.drawable.pic_nopic));
        image2.setScaleType(ScaleType.CENTER_INSIDE);
        contentView.addView(image1, new LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT));
        contentView.addView(image2, new LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT));

        indicator = new LinearLayout(mContext);
        SkinManager.setBackground(indicator, R.drawable.indicator_bg);
        indicator.setPadding(SkyConstants.Div(60), SkyConstants.Div(6), SkyConstants.Div(60), 0);
        contentView.addView(indicator, new LayoutParams(LayoutParams.WRAP_CONTENT,
                LayoutParams.WRAP_CONTENT, Gravity.CENTER_HORIZONTAL | Gravity.BOTTOM));
        indicator.setGravity(Gravity.CENTER_VERTICAL);

        leftArrow = new ImageView(mContext);
        rightArrow = new ImageView(mContext);
        SkinManager.setBackground(leftArrow, R.drawable.left_arrow_shot);
        SkinManager.setBackground(rightArrow, R.drawable.right_arrow_shot);

        indicatorText = UICommon.newTextView(mContext,
                SkyConstants.Dpi(30), R.color.defaultColor);
        indicatorText.setPadding(SkyConstants.Div(30), 0, SkyConstants.Div(30), 0);
        indicator.addView(leftArrow);
        indicator.addView(indicatorText);
        indicator.addView(rightArrow);
    }

    public void setContent(List<String> urlList, int index) {
        this.urlList = urlList;
        this.crtBitmapIndex = index;
        isLoaded = new boolean[urlList.size()];

        ImageView crtImage = getImageByIndex(crtImageIndex);
        bindImageWithBitmap(crtImage, index);
    }

    private ImageView getImageByIndex(int index) {
        if (index == 0)
            return image1;
        else if (index == 1)
            return image2;
        return null;
    }

    private void flipPrev() {
        if (crtBitmapIndex > 0 || circulate) {
            isRunningAnim = true;
            if (crtBitmapIndex > 0)
                crtBitmapIndex--;
            else
                crtBitmapIndex = urlList.size() - 1;

            ImageView crtImage = getImageByIndex(crtImageIndex);
            ImageView prevImage = getImageByIndex(1 - crtImageIndex);
            bindImageWithBitmap(prevImage, crtBitmapIndex);
            crtImage.startAnimation(outLeftRight);
            prevImage.startAnimation(inLeftRight);
            crtImageIndex = 1 - crtImageIndex;
        }
    }

    private void flipNext() {
        if (crtBitmapIndex < urlList.size() - 1 || circulate) {
            isRunningAnim = true;
            if (crtBitmapIndex < urlList.size() - 1)
                crtBitmapIndex++;
            else
                crtBitmapIndex = 0;

            ImageView crtImage = getImageByIndex(crtImageIndex);
            ImageView nextImage = getImageByIndex(1 - crtImageIndex);
            bindImageWithBitmap(nextImage, crtBitmapIndex);
            crtImage.startAnimation(outRightLeft);
            nextImage.startAnimation(inRightLeft);
            crtImageIndex = 1 - crtImageIndex;
        }
    }

    private void bindImageWithBitmap(ImageView image, int index) {
        image.setTag(index);
        if (isLoaded == null)
            isLoaded = new boolean[urlList.size()];
        if (isLoaded[index]) {
            if (getPreviewBitmap(index) != null) {
                image.setImageBitmap(getPreviewBitmap(index));
                image.setScaleType(ScaleType.FIT_XY);
            } else {
                image.setImageDrawable(SkinManager.getResDrawable(R.drawable.pic_nopic));
                image.setScaleType(ScaleType.CENTER_INSIDE);
            }
        } else {
            image.setImageDrawable(SkinManager.getResDrawable(R.drawable.pic_nopic));
            image.setScaleType(ScaleType.CENTER_INSIDE);
        }
        if (mainHandler.hasMessages(LOAD_BIG_BITMAP))
            mainHandler.removeMessages(LOAD_BIG_BITMAP);
        Message msg = mainHandler.obtainMessage(LOAD_BIG_BITMAP);
        msg.arg1 = index;
        mainHandler.sendMessageDelayed(msg, delayDuration);
    }

    private Bitmap getPreviewBitmap(int index) {
        if (listener != null && listener.getBitmapByIndex(index) != null)
            return listener.getBitmapByIndex(index);
        return null;
    }

    public void setPreviewListener(PreviewListener listener) {
        this.listener = listener;
    }


    private void showIndicator() {
        int bmCount = 0;
        if (urlList != null)
            bmCount = urlList.size();
        indicatorText.setText(String.format("%d/%d", crtBitmapIndex + 1, bmCount));
        if (!indicatorShown) {
            indicator.startAnimation(animShow);
        }

        if (circulate || crtBitmapIndex > 0)
            leftArrow.setVisibility(View.VISIBLE);
        else
            leftArrow.setVisibility(View.INVISIBLE);

        if (circulate || crtBitmapIndex < urlList.size() - 1)
            rightArrow.setVisibility(View.VISIBLE);
        else
            rightArrow.setVisibility(View.INVISIBLE);

        indicatorShown = true;
        if (mainHandler.hasMessages(HIDE_INDICATOR))
            mainHandler.removeMessages(HIDE_INDICATOR);
        mainHandler.sendEmptyMessageDelayed(HIDE_INDICATOR, showDuration);
    }

    private void hideIndicator() {
        indicator.startAnimation(animHide);
//        indicator.animate().y(SkyConstants.Div(-150)).setDuration(120);
        indicatorShown = false;
    }

    @Override
    public boolean onKeyDown(int keyCode, KeyEvent event) {
        // TODO Auto-generated method stub
        switch (keyCode) {
            case KeyEvent.KEYCODE_DPAD_LEFT:
                flipPrev();
                showIndicator();
                break;
            case KeyEvent.KEYCODE_DPAD_RIGHT:
                flipNext();
                showIndicator();
                break;
            case KeyEvent.KEYCODE_DPAD_CENTER:
                showIndicator();
                break;
        }
        return super.onKeyDown(keyCode, event);
    }

    @Override
    public void show() {
        // TODO Auto-generated method stub
        showIndicator();
        if (isLoaded == null) {
            if (urlList != null)
                isLoaded = new boolean[urlList.size()];
        }
        super.show();
    }

    @Override
    public void loadFinished(String url, Bitmap result) {
        // TODO Auto-generated method stub
        if (result == null) {
            LogUtils.d("recycle", "loadfinished, bitmap == null");
            return;
        }
        if (result.isRecycled()) {
            LogUtils.d("recycle", "loadfinished, bitmap is recycled");
            SkyNetImageCache.getSkyNetImageCache().downloadSreenShot(true,
                    url, this);
            return;
        }

        LogUtils.d("recycle", "loadfinished, bitmap is ok !!");
        Message msg = mainHandler.obtainMessage(REFRESH_IMAGE);
        msg.obj = result;
        Bundle data = new Bundle();
        data.putString("url", url);
        msg.setData(data);
        mainHandler.sendMessage(msg);
    }

    private Handler mainHandler = new Handler() {
        @Override
        public void handleMessage(Message msg) {
            // TODO Auto-generated method stub
            if (msg.what == REFRESH_IMAGE) {
                Bitmap result = (Bitmap) msg.obj;
                if (mDestrory) {
                    if (result != null && !result.isRecycled()) {
                        result.recycle();
                        result = null;
                    }
                }
                String url = msg.getData().getString("url");
                refreshImage(url, result);
            } else if (msg.what == HIDE_INDICATOR) {
                hideIndicator();
            } else if (msg.what == LOAD_BIG_BITMAP) {
                SkyNetImageCache.getSkyNetImageCache().downloadSreenShot(true,
                        urlList.get(msg.arg1), ShotDialog.this);
            }
            super.handleMessage(msg);
        }
    };

    String lastUrl = null;
    Bitmap lastBitmap = null;

    public void drawBitmap() {
        if (lastUrl == null || lastBitmap == null)
            return;
        refreshImage(lastUrl, lastBitmap);
    }

    private void refreshImage(String url, Bitmap bitmap) {
        if (!this.isShowing())
            return;
        if (bitmap == null || bitmap.isRecycled()) {
            SkyNetImageCache.getSkyNetImageCache().downloadSreenShot(true,
                    url, this);
            return;
        }
        if (isRunningAnim) {
            lastUrl = url;
            lastBitmap = bitmap;
            return;
        }
        lastUrl = null;
        lastBitmap = null;
        for (int i = 0; i < urlList.size(); i++) {
            if (urlList.get(i).equals(url)) {
                isLoaded[i] = true;
                int tag1 = (Integer) image1.getTag();
                if (tag1 == i && crtImageIndex == 0) {
                    image1.setImageBitmap(bitmap);
                    image1.setScaleType(ScaleType.FIT_XY);
                    if (loadedBitmap != null)
                        loadedBitmap.recycle();
                    loadedBitmap = bitmap;
                    image1.invalidate();
                    image2.setImageBitmap(null);
                    return;
                }
                int tag2 = (Integer) image2.getTag();
                if (tag2 == i && crtImageIndex == 1) {
                    image2.setImageBitmap(bitmap);
                    image2.setScaleType(ScaleType.FIT_XY);
                    if (loadedBitmap != null)
                        loadedBitmap.recycle();
                    loadedBitmap = bitmap;
                    image2.invalidate();
                    image1.setImageBitmap(null);
                    return;
                }
                break;
            }
        }
        bitmap.recycle();
    }

    private boolean mDestrory = false;

    public void destory() {
        mDestrory = true;
    }

    @Override
    public void dismiss() {
        image1.setImageBitmap(null);
        image2.setImageBitmap(null);
        hideIndicator();
        isLoaded = null;
        if (loadedBitmap != null) {
            loadedBitmap.recycle();
            loadedBitmap = null;
        }
        if (lastBitmap != null) {
            lastBitmap.recycle();
            lastBitmap = null;
        }
        super.dismiss();
    }

    public interface PreviewListener {
        public Bitmap getBitmapByIndex(int index);
    }
}
